//主题赛
const ResCode = require("../../config/ResCode");
const Stype = require("../../config/Stype");
const Cmd = require("../../config/Cmd");
const log = require('../../utils/log');
const RoomInfo = require('./roomInfo');
const {Respones} = require("../../config/gameCfg");
const game_zt_info = require('./game_tz_info');
const GameCfg = require("../../config/gameCfg");
const GameZtInfo = require("./game_tz_info");
const CmdHall = require('../proto/CmdHall');
const game_config = require('../../config/game_config');
const redisBase = require("../../common/RedisBase");

//保存到代码的客户端对象
function UserClient(_uid, _client){
    this.uid = _uid;
    this.client = _client;
    this.isReady = 0;// 准备状态 0是未准备 1 是准备
}

class hallZt{
    constructor() {
        //起始的房间id
        this.roomIdStart = 100001;

        //用来存放客户端对象
        this.item = {
            uid: 0,
            client:1,
        }
        this.roomSessions = {};
    }

    static getInstance(){
        if(!hallZt.instance){
            hallZt.instance = new hallZt();
            return hallZt.instance;
        }else{
            return hallZt.instance;
        }
    }

    //没有数据时候添加到rendis
     async addGameInfoToRedis(uid){
        let myIsNew = false; //标记我是否玩过主题赛
        let arr = [GameCfg.DWTYPE.DW_WENTI,GameCfg.DWTYPE.DW_ZUQIU,GameCfg.DWTYPE.DW_MINGZU];
        //判断redis里面是否存在用户数据
        let gameList = await redisBase.getGameListZt();
        for (let i = 0; i < gameList.length; i++) {
            let cfg = JSON.parse(gameList[i]);
            if(cfg.uid === uid){
                myIsNew = true;
                break;
            }
        }

        log.info("=======gameList=========",gameList.length);
        if(gameList.length <= 0 || !myIsNew){ //redis里面不存在
            log.info("=========手动添加=======")
            //手动添加
            let user = await redisBase.getUserInfo(uid);
            if(user){
                log.info('=======gameInfo=======',user)
                for (let i = 0; i < arr.length; i++) {
                    let gameInfo = new GameZtInfo(user.userId,user.name,user.avator,arr[i]);
                    await redisBase.addGameZtInfoInfoToList(gameInfo);
                }
            }
        }else{
            log.info('======已经存在======');
        }
        log.info('======addGameInfoToRedis end======');
    }

    //获取主题赛配置信息
    async theme_match_cfg_success(tmInfos,_type){
        let ret = {
            type: _type,
            data: {
                list:[]
            }
        }
        for (let i = 0; i < tmInfos.length; i++) {
            let cfg = tmInfos[i];
            let item = {
                type: cfg.gamType,
                people:0,
                dwType:cfg.dwLv,
                dwLv:cfg.dwLv,
                dwXzNum:cfg.dwXzNum,
                list:[]
            }

            let users = cfg.users;
            for (let j = 0; j < users.length; j++) {
                let temp = {
                    name:users[j].name,
                    avator:users[j].avator,
                    dwLv:users[j].dwLv,
                    dwXzNum:users[j].dwXzNum,
                }
                item.list.push(temp);
            }
            ret.data.list.push(item);
        }

        return ret;
    }


    //将房间号更新到redis gameInfo_list_zt
     updateRoomListInRedis(type, uid, roomId){
        return new Promise(async(resolve, reject)=>{
            let gameInfoList = await redisBase.getGameListZt();
            for (let i = 0; i < gameInfoList.length; i++) {
                let cfg = JSON.parse(gameInfoList[i]);
                if(cfg.gamType === type && cfg.uid === uid){
                    cfg.roomId = roomId;
                    await redisBase.updateGameListTzValue(i,JSON.stringify(cfg));
                    break;
                }
            }
            resolve();
        })
    }

    addClientInfo(uid,client,roomId){
        let user = new UserClient(uid,client);
        if(!this.roomSessions[roomId]){
            this.roomSessions[roomId]  = [];
        }
        this.roomSessions[roomId].push(user);
    }

    updateClient(roomId, uid, client){
        let roomInfo = this.roomSessions[roomId];
        if(roomInfo){
            for (let i = 0; i < roomInfo.length; i++) {
                if(roomInfo[i].uid === uid){
                    roomInfo[i].client = client;
                    break;
                }
            }
        }
    }

    async create_room(uid, client,gameType){
        let roomId = this.roomIdStart++;
        let room = new RoomInfo(roomId,gameType);
        room.do_enter_room(uid);

        //保存客户端的session
        this.addClientInfo(uid,client,roomId);

        //将房间加入到房间列表
        let info = room.getRoomInfo()
        log.info('=====新房间信息====', info);
        await redisBase.addRoomInfoToList(info);

        //将房间号记录到gameInfo——list 里面
        await this.updateRoomListInRedis(gameType,uid,info.roomId);
    }


    async saveRoomIdTogameInfo_list_zt(uid, gameType,roomId){
        let gameInfoList = await redisBase.getGameListZt();
        if(gameInfoList){
            for (let i = 0; i < gameInfoList.length; i++) {
                let cfg = JSON.parse(gameInfoList[i]);
                if(cfg.uid === uid && cfg.gamType === gameType){
                    cfg.roomId = roomId;
                    await redisBase.updateGameListTzValue(i,JSON.stringify(cfg));
                    break;
                }
            }
        }else{
            log.error("==获取Redis 里面列表 gameInfo_list_zt 出错==");
        }
    }

    //开始匹配（创建房间）
    async theme_match_start_pp(data,client,ctype){
        let uid = data.userId;
        let gametype = data.type;

        //step1:搜索房间列表里面有没有空的位置
         let roomInfo = await redisBase.getValidRoomInList();
         log.error('========theme_match_start_pp==========',roomInfo);
         if(roomInfo.length === 0) { //没有创建一个新的房间
             //创建一个新房间
             await this.create_room(uid,client,gametype);

             let ret = {
                 type: ctype,
                 data: {
                     code: Respones.INVALID,
                 }
             }
             return ret;
         }else{ //有就判断有没有空座位
             for (let i = 0; i < roomInfo.length; i++) {
                 let cfg  = JSON.parse(roomInfo[i]);
                 if(cfg.players.indexOf(null) !== -1){ //有空座位做下
                     log.info("=====表示有空座位========");
                     if(cfg.players.indexOf(uid) === -1){ //房间不是我创建的
                         log.info("=====表示有空座位,我可以加入========");
                         let idx=  cfg.players.indexOf(null);
                         cfg.players[idx] = uid;
                         log.info("=====updateRoomListValue========");
                         await redisBase.updateRoomListValue(i,JSON.stringify(cfg));

                         //保存客户端的session
                         this.addClientInfo(uid,client,cfg.roomId);

                         //将房间号记录到gameInfo——list 里面
                         await this.updateRoomListInRedis(gametype,uid,cfg.roomId);

                         let ret = this.getRoomDataRes(ctype,cfg.roomId);

                         log.info("=====我加入别人创建好的房间========");
                         //这里广播匹配成功
                         this.broadPiPeiSuccess(cfg.roomId,gametype);
                         return ret;
                     }else {
                         log.info("=====表示有空座位,我创建的房间========");
                     }
                     //将我加入新座位，并返回
                 }else if(cfg.players.indexOf(null) == -1 && cfg.players.indexOf(uid) === -1){ //没有空座位,坐满了
                     log.info("=====没有空座位,坐满了，创建一个新房间========");
                     //创建一个新房间
                     await this.create_room(uid,client,gametype);

                     let ret = {
                         type: ctype,
                         data: {
                             code: Respones.INVALID,
                         }
                     }
                     return ret;
                 }else if(cfg.players.indexOf(null) == -1 && cfg.players.indexOf(uid) !== -1) { //我在这个房间里
                     log.info('====我在这个房间里====');
                     //保存客户端的session
                     this.addClientInfo(uid,client,cfg.roomId);

                     let ret = this.getRoomDataRes(ctype,cfg.roomId);
                     //这里广播匹配成功
                     this.broadPiPeiSuccess(cfg.roomId,gametype);
                     return ret;
                 }
             }
         }

        log.info('=======房间已经创建======')
        let ret = {
            type: ctype,
            data: {
                code: Respones.INVALID,
            }
        }
        return ret;
    }

    //广播匹配结果
    async broadPiPeiSuccess(roomId,gametype){
         log.info('==========broadPiPeiSuccess===========',roomId,gametype);
        let info = this.roomSessions[roomId];
        log.info('==========broadPiPeiSuccess===========',info.length);

        //匹配成功直接开始游戏
        let ret = {
            type: CmdHall.ThemeMatchPPBroad,
            data: {
                gameNet:{
                    ip:game_config.game_server.host,
                    port:game_config.game_server.port
                }
            }
        }
        if(info){
            for (let i = 0; i < info.length; i++) {
                let client = info[i].client;
                log.info('==========broadPiPeiSuccess end===========',i);
                client.send(JSON.stringify(ret));
            }
        }else{
            log.error('======session===is null====',roomId.gameType);
        }
        // log.info("================ret==============",ret);

    }

    //匹配成功
   async getRoomDataRes(ctype,roomId){
       let ret = {
           type: ctype,
           data: {
               code:Respones.OK,
           }
       }
       return ret;
    }


    //广播房间解散
    broadRoomJieSan(roomId){
        let res = {
            type: CmdHall.ThemeMatchJieSanBroad,
            data:{
                code:Respones.OK
            }
        }
        log.info('======广播结算结果=======');
        let roomInfos = this.roomSessions[roomId];
        for (let i = 0; i < roomInfos.length; i++) {
            let cfg = roomInfos[i];
            let client = cfg.client;
            client.send(JSON.stringify(res));
        }
    }

    //停止匹配（离开房间）
    async theme_match_stop_pp(data,ctype){
        let uid = data.userId;
        let gametype = data.type;

        //移除数据
        await this.theme_match_discannect_clear_roomInfo(uid);

        let roomInfo = await redisBase.getValidRoomInList();
        log.error('========theme_match_stop_pp==========',roomInfo);
        for (let i = 0; i < roomInfo.length; i++) {
            let cfg = JSON.parse(roomInfo[i]);
            let roomId = cfg.roomId;
            let idx = cfg.players.indexOf(uid);
            if(idx !== -1){
                if(cfg === 0){
                    log.info('======表示是解散我自己创建的房间=========');
                }else if(cfg === 1){
                    log.info('======表示是我离开别人的房间的房间=========');
                }
                this.broadRoomJieSan(roomId);
                break;
            }
        }

        let res = {
            type: ctype,
            data:{
                code:Respones.OK
            }
        }
        log.info('====theme_match_stop_pp=====',res)
        return res;
    }

    //广播开始游戏
    broad_game_start(roomId){
        // 标记玩家准备状态

        //标记是否都准备完毕了
        let isRedayOver = true;
        let roomInfo = this.roomSessions[roomId];
        for (let i = 0; i < roomInfo.length; i++) {
            let item = roomInfo[i];
            if(item.isReady === 0){//准备状态 1是已准备 0是未准备
                isRedayOver = false;
                break;
            }
        }
        log.info('======broad_game_start========',isRedayOver);
        if(isRedayOver){
            log.warn("=======广播开始游戏=======房间号：",roomId);
            for (let i = 0; i < roomInfo.length; i++) {
                let item = roomInfo[i];
                let client = item.client;
                let res = {
                    type: CmdHall.ThemeMatchStarBroad,
                    data:{
                        code:Respones.OK,
                        gameNet:{
                            ip:game_config.game_server.host,
                            port:game_config.game_server.port
                        }
                    }
                }
                log.warn("=======广播开始游戏=======：",item.uid);
                client.send(JSON.stringify(res));
            }
        }
    }

    /**
     * 主题赛开始游戏
     * @param data
     * @returns {Promise<void>}
     */
    async theme_match_star_game(data,ctype,client){
        let uid = data.userId;
        let gameType = data.type;
        let roomId = data.roomId;

        let res;

        //更新客户端对象
        this.updateClient(roomId,uid,client);

        log.info("======theme_match_star_game1=======",data)

        let gameInfoList = await redisBase.getGameListZt();
        for (let i = 0; i < gameInfoList.length; i++) {
            let cfg = JSON.parse(gameInfoList[i]);
            if(cfg.gamType === gameType && cfg.uid === uid){
                cfg.gameStatus = 2; //2是准备状态 1 是未准别状态
                await redisBase.updateGameListTzValue(i,JSON.stringify(cfg));
                break;
            }
        }

        log.info("======theme_match_star_game=======",this.roomSessions)
        // 标记玩家准备状态
        let roomInfo = this.roomSessions[roomId];
        for (let i = 0; i < roomInfo.length; i++) {
            let item = roomInfo[i];
            if(item.uid === uid){
                item.isReady = 1; //设置为准备状态
                break;
            }
        }

        // 检测两个人是否都准备了，都准备了就开始游戏
        setTimeout(()=>{
            this.broad_game_start(roomId);
        },500);

        res = {
            type: ctype,
            data:{
                code:Respones.OK,
            }
        }
        return res;
    }

    //断线亲空玩家对应的房间信息
    async theme_match_discannect_clear_roomInfo(uid) {
        let roomList = await redisBase.getValidRoomInList();
        for (let i = 0; i < roomList.length; i++) {
                let cfg = JSON.parse(roomList[i]);
                let gameType = cfg.gameTypeZt;
                let idx = cfg.players.indexOf(uid);
                if (idx !== -1) { //表示我存在
                    if (idx === 0) { //我创建的房间
                        //移除房间信息
                        await redisBase.delRooomList(i, JSON.stringify(cfg));
                        //移除自己
                        this.removeFromGameInfoList(gameType, uid);
                        //移除其他人
                        let uid2 = cfg.players[1];
                        if (uid2) {
                            this.removeFromGameInfoList(gameType, uid2);
                        }
                    } else if (idx === 1) { //我加入的房间
                        log.info('=======我加入的房间=======');
                        //从当前房间移除自己
                        cfg.players[idx] = null;
                        //移除自己
                        this.removeFromGameInfoList(gameType, uid);
                        //更新房间信息
                        log.info('=======updateRoomListValue=======')
                        await redisBase.updateRoomListValue(i, JSON.stringify(cfg));
                    }
                    break;
                }
            }

    }

    /**
     * 从列表 gameInfo_list_zt 里面移除 房间信息
     * @param gameType 主题类型 1文体 2足球 3民族
     * @param uid
     */
   async removeFromGameInfoList(gameType,uid){
        let gamelist = await redisBase.getGameListZt();
        for (let i = 0; i < gamelist.length; i++) {
            let cfg =  JSON.parse(gamelist[i]);
            if(cfg.uid === uid && cfg.gamType === gameType){
                cfg.roomId = 0;
                await redisBase.updateGameListTzValue(i,JSON.stringify(cfg));
                break;
            }
        }
    }
}
module.exports = hallZt.getInstance();